
import time
import re
import math
import traceback
import sys
import copy
import random
from types import DictType
import wtsglobal

NoneBuiltin = {'__builtins__': None, 'True':True, 'False':False, "len":len}
TIME_FIELD = "__Time__"
DATATYPE_FIELD = "__DataType__"
NeighborListPattern = re.compile(r'\(([0-9]+?), ([0-9]+?)\)')
#TICKS_PER_SENCOND = 1.0E+6
TICKS_PER_SENCOND = 1.0E+3

class WTSException(Exception):
    pass

def str2hex(s): 
    return " ".join(["%02X" % ord(k) for k in s])
    
def calc(expr, env, defvalue="True"):
    if expr.strip()=="":
        # Nothing means all ok!
        return defvalue
    else:
        try:
            r = eval(expr, NoneBuiltin, env)
            return r
        except:
            return False

def timenow():
    return time.time()
    
def time2str(t, showMicrosencod=True):
    strt = time.strftime( "%Y/%m/%d %H:%M:%S", time.localtime(t))
    if showMicrosencod:
        ms = int(math.modf(t)[0]*1E+3)
        return "%s.%03d" % (strt, ms)
    else:
        return strt

def str2time(s):
    if s[-4]=='.':
        ms = int(s[-3:])/1E+3
        s = s[:-4]
    else:
        ms = 0
    return time.mktime(time.strptime(s,"%Y/%m/%d %H:%M:%S"))+ms
    
def printExp():
    type, value, tb = sys.exc_info()
    print traceback.format_exception(type, value, tb)

def speed2interval(s):
    return 10.0**(s/10.0)
    
class Enum:
    def __init__(self, **kw):
        self.__dict__.update(kw) 

def iterNeighborList(s):
    return [(int(i[0]),int(i[1])) for i in re.findall(NeighborListPattern, s)]

def debug(f):
    """
    Decorator; Used for debug
    """
    def debug_f(*para):
        print "[BEGIN Function]",f.func_name
        try:
            f(*para)
        except:
            type, value, tb = sys.exc_info()
            print traceback.format_exception(type, value, tb)
        else:
            print "[END Function]",f.func_name
    return debug_f

class RandomGenerator:
    """class for generator random value"""
    
    def __init__(self, minValue, maxValue):
        """
        Set the generaror's min/max
        """
        self.minValue = minValue
        self.maxValue = maxValue

    def GetValue(self):
        """
        get random value
        @return: random value, between min and max (both included)
        """
        return random.randrange(self.minValue, self.maxValue+1)
    
class ConstGenerator:
    """class for generator const value"""
    
    def __init__(self, value):
        """
        Set the const value
        """
        self.value = value

    def GetValue(self):
        """
        get const value
        @return: const value, the same as options.value
        """
        return self.value

def generatorAutoCommand(cmd_name, defaultValue=None, **args): # send cmd, with const/random/sequence/time value auto setting
    now = timenow()
    time_second = int(now)
    time_ticks = int((now-int(now))*TICKS_PER_SENCOND)
    cmd = wtsglobal.commandByName[cmd_name]
    if not isinstance(defaultValue,dict):
        defaultValue = {}
    cmdparas = {}
    cmdparas["name"]=cmd.name
    for fieldName,dumb_1,dumb_2,dumb_3,valueType,options in cmd.fields:
        if fieldName in args:
            cmdparas[fieldName] = args[fieldName]
        elif fieldName in defaultValue:
            cmdparas[fieldName] = defaultValue[fieldName]
        else:
            if valueType=="time_second":
                cmdparas[fieldName] = time_second
            elif valueType=="time_ticks":
                cmdparas[fieldName] = time_ticks
            elif valueType=="const":
                cmdparas[fieldName] = options["value"]
            elif valueType=="random":
                cmdparas[fieldName] = random.randrange(options["min"],options["max"]+1)
            elif valueType=="unique8":
                if not hasattr(wtsglobal, "sequence"):
                    initSequence()
                cmdparas[fieldName] = wtsglobal.sequence[wtsglobal.cur_sequence_pos]
                wtsglobal.cur_sequence_pos = (wtsglobal.cur_sequence_pos + 1) % 256
            else:
                raise WTSException # "No Value for Fieldname %s" % fieldName
    #print "######cmdparas:",cmdparas
    return cmdparas

def autoSendCommand(wsnSource, cmd_name, defaultValue=None, **args):
    cmdparas = generatorAutoCommand(cmd_name,defaultValue, **args)
    wsnSource.sendCommand(cmdparas)
    return cmdparas.get("Sequence", None), cmdparas
    
def initSequence():
    wtsglobal.cur_sequence_pos = 0
    wtsglobal.sequence= range(0,256)
    random.shuffle(wtsglobal.sequence)
    #print wtsglobal.sequence

if __name__ == "__main__":
    t = timenow()
    s = time2str(t)
    t2 = str2time(s)
    print t,s,t2
    assert t == t2
    print calc("__Time__>5",{"__Time__":6})